package com.af.community.smart.utils

import android.annotation.SuppressLint
import android.content.Context
import android.view.View
import android.widget.TextView
import com.af.community.smart.base.*
import com.af.community.smart.business.R
import com.af.community.smart.model.CityData
import com.flyco.dialog.entity.DialogMenuItem
import com.flyco.dialog.widget.ActionSheetDialog
import com.maning.mndialoglibrary.MProgressDialog
import com.weigan.loopview.LoopView
import java.util.*
import kotlin.collections.ArrayList

object DialogHelper {

    @SuppressLint("StaticFieldLeak")
    private var mMProgressDialog: MProgressDialog? = null

    fun showDialog(context: Context, hint: String = "") {
        dismissDialog()

        mMProgressDialog = MProgressDialog.Builder(context)
            .setCancelable(true)
            .isCanceledOnTouchOutside(false)
            .setDimAmount(0.5f)
            .build()
        mMProgressDialog!!.show(hint)
    }

    fun dismissDialog() {
        if (mMProgressDialog != null && mMProgressDialog!!.isShowing)
            mMProgressDialog!!.dismiss()
    }

    fun Context.showListDialog(
        vararg params: String,
        listener: (Int, String) -> Unit
    ) {
        ActionSheetDialog(this, params, null).apply {
            isTitleShow(false)
            lvBgColor(getColorEx(R.color.white))
            itemTextColor(getColorEx(R.color.black))
            itemHeight(45f)
            itemTextSize(15f)
            dividerHeight(0.5f)
            dividerColor(getColorEx(R.color.divider_dark))
            cancelText(getColorEx(R.color.light))
            cancelTextSize(15f)
            layoutAnimation(null)
            show()

            setOnOperItemClickL { _, _, index, _ ->
                dismiss()
                listener.invoke(index, params[index])
            }
        }
    }

    fun Context.showListDialog(
        list: ArrayList<DialogMenuItem>,
        listener: (DialogMenuItem) -> Unit
    ) {
        ActionSheetDialog(this, list, null).apply {
            isTitleShow(false)
            lvBgColor(getColorEx(R.color.white))
            itemTextColor(getColorEx(R.color.black))
            itemHeight(45f)
            itemTextSize(15f)
            dividerHeight(0.5f)
            dividerColor(getColorEx(R.color.divider_dark))
            cancelText(getColorEx(R.color.light))
            cancelTextSize(15f)
            layoutAnimation(null)
            show()

            setOnOperItemClickL { _, _, index, _ ->
                dismiss()
                listener.invoke(list[index])
            }
        }
    }

    fun Context.showItemDialog(
        title: String = "请选择",
        index: Int = -1,
        items: List<String>,
        listener: (Int, String) -> Unit
    ) {

        val dialog = object : BottomDialog(this) {

            private lateinit var loopView: LoopView

            override fun onCreateView(): View {
                val view = inflate<View>(R.layout.dialog_select_one)

                val tvTitle = view.findViewById<TextView>(R.id.tv_dialog_select_title)
                val tvCancel = view.findViewById<TextView>(R.id.tv_dialog_select_cancle)
                val tvOk = view.findViewById<TextView>(R.id.tv_dialog_select_ok)
                loopView = view.findViewById(R.id.lv_dialog_select_loop)

                tvTitle.text = title
                loopView.setTextSize(15f)
                loopView.setDividerColor(getColorEx(R.color.divider_dark))
                loopView.setNotLoop()

                tvCancel.oneClick { dismiss() }

                tvOk.oneClick {
                    dismiss()
                    listener.invoke(loopView.selectedItem, items[loopView.selectedItem])
                }

                return view
            }

            override fun setUiBeforShow() {
                loopView.setItems(items)
                loopView.setInitPosition(if (index < 0) 0 else index)
            }

        }

        dialog.show()
    }

    fun Context.showCityDialog(
        title: String = "请选择",
        list: List<CityData> = ArrayList(),
        listener: (String, String, String, String, String, String) -> Unit = { _, _, _, _, _, _ -> }
    ) {
        if (list.isEmpty()) return

        val dialog = object : BottomDialog(this) {

            private lateinit var loopProvince: LoopView
            private lateinit var loopCity: LoopView
            private lateinit var loopArea: LoopView

            override fun onCreateView(): View {
                val view = inflate<View>(R.layout.dialog_select_area)

                val tvTitle = view.findViewById<TextView>(R.id.tv_dialog_select_title)
                val tvCancel = view.findViewById<TextView>(R.id.tv_dialog_select_cancle)
                val tvOk = view.findViewById<TextView>(R.id.tv_dialog_select_ok)

                loopProvince = view.find(R.id.lv_dialog_select_province)
                loopCity = view.find(R.id.lv_dialog_select_city)
                loopArea = view.find(R.id.lv_dialog_select_area)

                tvTitle.text = title

                loopProvince.setTextSize(14f)
                loopCity.setTextSize(14f)
                loopArea.setTextSize(14f)

                loopProvince.setDividerColor(getColorEx(R.color.divider_dark))
                loopCity.setDividerColor(getColorEx(R.color.divider_dark))
                loopArea.setDividerColor(getColorEx(R.color.divider_dark))

                loopProvince.setNotLoop()
                loopCity.setNotLoop()
                loopArea.setNotLoop()

                tvCancel.oneClick { dismiss() }

                tvOk.oneClick {
                    val indexProvince = loopProvince.selectedItem
                    val indexCity = loopCity.selectedItem
                    val indexArea = loopArea.selectedItem

                    val provinceName = list[indexProvince].name
                    val cityName = list[indexProvince].charp[indexCity].name
                    val areaName = list[indexProvince].charp[indexCity].charp[indexArea].name

                    val provinceCode = list[indexProvince].code
                    val cityCode = list[indexProvince].charp[indexCity].code
                    val areaCode = list[indexProvince].charp[indexCity].charp[indexArea].code

                    dismiss()
                    listener.invoke(
                        provinceName,
                        cityName,
                        areaName,
                        provinceCode,
                        cityCode,
                        areaCode
                    )
                }

                return view
            }

            override fun setUiBeforShow() {
                val listProvince = ArrayList<String>()
                val listCity = ArrayList<String>()
                val listArea = ArrayList<String>()

                list.mapTo(listProvince) { it.name }
                list[0].charp.mapTo(listCity) { it.name }
                list[0].charp[0].charp.mapTo(listArea) { it.name }

                loopProvince.setItems(listProvince)
                loopCity.setItems(listCity)
                loopArea.setItems(listArea)

                loopCity.setListener {
                    val index1 = loopProvince.selectedItem
                    val index2 = loopCity.selectedItem

                    listArea.clear()
                    list[index1].charp[index2].charp.mapTo(listArea) { it.name }

                    loopArea.setItems(listArea)

                    loopArea.setCurrentPosition(0)
                }

                loopProvince.setListener {
                    val index = loopProvince.selectedItem

                    listCity.clear()
                    listArea.clear()

                    list[index].charp.mapTo(listCity) { it.name }
                    list[index].charp[0].charp.mapTo(listArea) { it.name }

                    loopCity.setItems(listCity)
                    loopArea.setItems(listArea)

                    loopCity.setCurrentPosition(0)
                    loopArea.setCurrentPosition(0)
                }
            }

        }

        dialog.show()
    }

    /**
     * 时间选择器（R.layout.dialog_select_more 布局文件）
     * @param minYearValue    最小年份
     * @param maxYearValue    最大年份
     * @param count           年、月、日、时、分、秒的显示个数
     * @param title           标题
     * @param initYear        默认年
     * @param initMonth       默认月
     * @param initDay         默认日
     * @param initHour        默认时
     * @param initMinute      默认分
     * @param isCurrentDate   是否默认选择当天日期（与默认年、月、日、时、分互斥）
     * @param isBeforeLimited 是否限制选择该年内，当天前的日期
     * @param isAfterLimited  是否限制选择该年内，当天后的日期（前后日期互斥）
     * @param callback        回调接口
     */
    fun Context.showDateDialog(
        minYearValue: Int = 1900,
        maxYearValue: Int = 2100,
        count: Int = 5,
        title: String = "请选择",
        initYear: Int = -1,
        initMonth: Int = -1,
        initDay: Int = -1,
        initHour: Int = -1,
        initMinute: Int = -1,
        isCurrentDate: Boolean = true,
        isBeforeLimited: Boolean = false,
        isAfterLimited: Boolean = false,
        callback: (Int, Int, Int, Int, Int, String) -> Unit = { _, _, _, _, _, _ -> }
    ) {

        val dialog = object : BottomDialog(this) {

            private lateinit var loopYear: LoopView
            private lateinit var loopMonth: LoopView
            private lateinit var loopDay: LoopView
            private lateinit var loopHour: LoopView
            private lateinit var loopMinute: LoopView

            override fun onCreateView(): View {
                val view = inflate<View>(R.layout.dialog_select_more)

                val tvTitle = view.findViewById<TextView>(R.id.tv_dialog_select_title)
                val tvCancel = view.findViewById<TextView>(R.id.tv_dialog_select_cancle)
                val tvOk = view.findViewById<TextView>(R.id.tv_dialog_select_ok)

                loopYear = view.find(R.id.lv_dialog_select_year)
                loopMonth = view.find(R.id.lv_dialog_select_month)
                loopDay = view.find(R.id.lv_dialog_select_day)
                loopHour = view.find(R.id.lv_dialog_select_hour)
                loopMinute = view.find(R.id.lv_dialog_select_minute)

                tvTitle.text = title

                loopYear.setTextSize(15f)
                loopMonth.setTextSize(15f)
                loopDay.setTextSize(15f)
                loopHour.setTextSize(15f)
                loopMinute.setTextSize(15f)

                loopYear.setDividerColor(getColorEx(R.color.divider_dark))
                loopMonth.setDividerColor(getColorEx(R.color.divider_dark))
                loopDay.setDividerColor(getColorEx(R.color.divider_dark))
                loopHour.setDividerColor(getColorEx(R.color.divider_dark))
                loopMinute.setDividerColor(getColorEx(R.color.divider_dark))

                loopYear.setNotLoop()
                loopMonth.setNotLoop()
                loopDay.setNotLoop()
                loopHour.setNotLoop()
                loopMinute.setNotLoop()

                when (count) {
                    1 -> {
                        loopMonth.gone()
                        loopDay.gone()
                        loopHour.gone()
                        loopMinute.gone()
                    }
                    2 -> {
                        loopDay.gone()
                        loopHour.gone()
                        loopMinute.gone()
                    }
                    3 -> {
                        loopHour.gone()
                        loopMinute.gone()
                    }
                    4 -> loopMinute.gone()
                }

                tvCancel.oneClick { dismiss() }

                tvOk.oneClick {

                    val year = loopYear.selectedItem + minYearValue
                    var month = loopMonth.selectedItem + 1
                    var day = loopDay.selectedItem + 1
                    val hour = loopHour.selectedItem
                    val minute = loopMinute.selectedItem

                    val calendar = Calendar.getInstance()
                    val yearNow = calendar.get(Calendar.YEAR)
                    val monthNow = calendar.get(Calendar.MONTH)
                    val dayNow = calendar.get(Calendar.DAY_OF_MONTH)

                    var dateNew: String

                    if (isBeforeLimited && year == yearNow) {
                        if (month < monthNow + 1) {
                            month = monthNow + 1
                            day = dayNow
                        }
                        if (month == monthNow + 1 && day < dayNow) day = dayNow
                    }

                    if (isAfterLimited && year == yearNow) {
                        if (month > monthNow + 1) {
                            month = monthNow + 1
                            day = dayNow
                        }
                        if (month == monthNow + 1 && day > dayNow) day = dayNow
                    }

                    when (count) {
                        1 -> dateNew = year.toString() + "年"
                        2 -> {
                            dateNew = if (month < 10) "$year-0$month" else "$year-$month"
                        }
                        3 -> {
                            dateNew = when {
                                month < 10 && day < 10 -> "$year-0$month-0$day"
                                month < 10 && day >= 10 -> "$year-0$month-$day"
                                month >= 10 && day < 10 -> "$year-$month-0$day"
                                else -> "$year-$month-$day"
                            }
                        }
                        4 -> {
                            dateNew = when {
                                month < 10 && day < 10 -> "$year-0$month-0$day ${hour}时"
                                month < 10 && day >= 10 -> "$year-0$month-$day ${hour}时"
                                month >= 10 && day < 10 -> "$year-$month-0$day ${hour}时"
                                else -> "$year-$month-$day ${hour}时"
                            }
                        }
                        else -> {
                            dateNew = when {
                                month < 10 && day < 10 -> "$year-0$month-0$day"
                                month < 10 && day >= 10 -> "$year-0$month-$day"
                                month >= 10 && day < 10 -> "$year-$month-0$day"
                                else -> "$year-$month-$day"
                            }

                            when {
                                hour < 10 && minute < 10 -> dateNew += " 0$hour:0$minute"
                                hour < 10 && minute >= 10 -> dateNew += " 0$hour:$minute"
                                hour >= 10 && minute < 10 -> dateNew += " $hour:0$minute"
                                hour >= 10 && minute >= 10 -> dateNew += " $hour:$minute"
                            }
                        }
                    }

                    dismiss()
                    callback.invoke(year, month, day, hour, minute, dateNew)
                }

                return view
            }

            override fun setUiBeforShow() {
                loopYear.setItems(dateToList(minYearValue, maxYearValue, "%d年"))
                loopMonth.setItems(dateToList(1, 12, "%d月"))
                loopDay.setItems(dateToList(1, 31, "%d日"))
                loopHour.setItems(dateToList(0, 23, "%d时"))
                loopMinute.setItems(dateToList(0, 59, "%d分"))

                if (isCurrentDate) {
                    loopYear.setInitPosition(Calendar.getInstance().get(Calendar.YEAR) - minYearValue)
                    loopMonth.setInitPosition(Calendar.getInstance().get(Calendar.MONTH))
                    loopDay.setInitPosition(Calendar.getInstance().get(Calendar.DAY_OF_MONTH) - 1)
                } else {
                    if (initYear > -1 && initMonth > -1 && initDay > -1 && initHour > -1 && initMinute > -1) {
                        loopYear.setInitPosition(initYear - minYearValue)
                        loopMonth.setInitPosition(initMonth)
                        loopDay.setInitPosition(initDay - 1)
                        loopHour.setInitPosition(initHour)
                        loopMinute.setInitPosition(initMinute)
                    }
                }

                val listBig = listOf(1, 3, 5, 7, 8, 10, 12)
                val listLittle = listOf(4, 6, 9, 11)

                loopMonth.setListener {
                    val monthNum = loopMonth.selectedItem + 1
                    // 判断大小月及是否闰年,用来确定"日"的数据
                    if (monthNum in listBig) {
                        loopDay.setItems(dateToList(1, 31, "%d日"))
                    } else if (monthNum in listLittle) {
                        loopDay.setItems(dateToList(1, 30, "%d日"))
                        if (loopDay.selectedItem == 30) loopDay.setCurrentPosition(29)
                    } else {
                        if ((loopYear.selectedItem + minYearValue) % 4 == 0
                            && (loopYear.selectedItem + minYearValue) % 100 != 0
                            || (loopYear.selectedItem + minYearValue) % 400 == 0
                        ) {
                            loopDay.setItems(dateToList(1, 29, "%d日"))
                            if (loopDay.selectedItem >= 29)
                                loopDay.setCurrentPosition(28)
                        } else {
                            loopDay.setItems(dateToList(1, 28, "%d日"))
                            if (loopDay.selectedItem >= 28)
                                loopDay.setCurrentPosition(27)
                        }
                    }
                }

                loopYear.setListener {
                    val yearNum = loopYear.selectedItem + minYearValue
                    // 判断大小月及是否闰年,用来确定"日"的数据
                    if ((loopMonth.selectedItem + 1) in listBig) {
                        loopDay.setItems(dateToList(1, 31, "%d日"))
                    } else if ((loopMonth.selectedItem + 1) in listLittle) {
                        loopDay.setItems(dateToList(1, 30, "%d日"))
                    } else {
                        if (yearNum % 4 == 0
                            && yearNum % 100 != 0
                            || yearNum % 400 == 0
                        )
                            loopDay.setItems(dateToList(1, 29, "%d日"))
                        else {
                            loopDay.setItems(dateToList(1, 28, "%d日"))
                            if (loopDay.selectedItem == 28)
                                loopDay.setCurrentPosition(27)
                        }
                    }
                }
            }

        }

        dialog.show()
    }

    private fun dateToList(minValue: Int, maxValue: Int, format: String?): List<String> {
        val items = ArrayList<String>()
        for (i in 0 until maxValue - minValue + 1) {
            val value = minValue + i
            items.add(if (format != null) String.format(format, value) else value.toString())
        }
        return items
    }

}